#pragma once
/* Image.h - Header file for outputing images and types */
#include <cstdint>
#include <string>
#include <ostream>
#include <cmath>

#pragma pack(push, 1)
struct bmpFileHeader
{
	uint8_t b;
	uint8_t m;
	uint32_t size;
	uint16_t reserved;
	uint16_t reserved2;
	uint32_t offset;
};

struct DIBHeader
{
	uint32_t size;
	uint32_t width;
	uint32_t height;
	uint16_t planes;
	uint16_t bits_per_pixel;
	uint32_t compression;
	uint32_t imageSize;
	int32_t hres;
	int32_t vres;
	uint32_t numcolors;
	uint32_t numimportantcolors;
};
#pragma pack(pop)

class Pixel
{
public:
	float r;
	float g;
	float b;
	float a;
	Pixel(float _r = 0, float _g = 0, float _b = 0, float _a = 0)
		: r(_r), g(_g), b(_b), a(_a)
	{
	}
	void Map2Bmp(/*out*/uint8_t *bgr)
	{
		Clamp();
		bgr[0] = (uint8_t)(b * 255);
		bgr[1] = (uint8_t)(g * 255);
		bgr[2] = (uint8_t)(r * 255);
	}
	void Clamp()
	{
		r = std::max(r,0.0f);
		g = std::max(g,0.0f);
		b = std::max(b,0.0f);
		r = std::min(r,1.0f);
		g = std::min(g,1.0f);
		b = std::min(b,1.0f);
	}
};


class Image
{
	//for now we will support 32 bit images in RGBA format
	int height;
	int width;
	Pixel *data;
public:
	Image(int h, int w)
		:height(h), width(w)
	{
		data = new Pixel[height * width];
	}

	Pixel& operator()(unsigned int i, unsigned int j)
	{
		return data[j*width + i];
	}

	int WriteToBitmap(const std::string filename);
};